package com.tm.util;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyStore;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jsoup.Jsoup;
import org.jsoup.select.Elements;

import com.tm.ResultEntity;
import com.tm.pay.config.WechatConfig;

public class CommonUtilsEx {

	/**
	 * 获取客户端IP
	 * 
	 * @param request
	 * @return String
	 */
	public static String getIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

	/**
	 * 数字转换为字符串
	 * 
	 * @param n
	 */
	public static String inttostring(int n, int length) {
		/* 创建length长度的字符串，每一个字符为'0' */
		String str = "";
		for (int i = 0; i < length; i++) {
			str += "0";
		}
		/* 将n转换为字符串 */
		String str_m = String.valueOf(n);
		/* 字符串左填充0 */
		str_m = str.subSequence(0, length - str_m.length()) + str_m;
		return str_m;
	}

	public static Map doXMLParse(String strxml) throws JDOMException,
			IOException {
		strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");

		if (null == strxml || "".equals(strxml)) {
			return null;
		}

		Map m = new HashMap();

		InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
		SAXBuilder builder = new SAXBuilder();
		Document doc = builder.build(in);
		Element root = doc.getRootElement();
		List list = root.getChildren();
		Iterator it = list.iterator();
		while (it.hasNext()) {
			Element e = (Element) it.next();
			String k = e.getName();
			String v = "";
			List children = e.getChildren();
			if (children.isEmpty()) {
				v = e.getTextNormalize();
			} else {
				v = getChildrenText(children);
			}

			m.put(k, v);
		}

		// 关闭流
		in.close();

		return m;
	}

	public static String getChildrenText(List children) {
		StringBuffer sb = new StringBuffer();
		if (!children.isEmpty()) {
			Iterator it = children.iterator();
			while (it.hasNext()) {
				Element e = (Element) it.next();
				String name = e.getName();
				String value = e.getTextNormalize();
				List list = e.getChildren();
				sb.append("<" + name + ">");
				if (!list.isEmpty()) {
					sb.append(getChildrenText(list));
				}
				sb.append(value);
				sb.append("</" + name + ">");
			}
		}
		return sb.toString();
	}

	/**
	 * 向指定 URL 发送POST方法的请求
	 * 
	 * @param url
	 *            发送请求的 URL
	 * @param param
	 *            请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
	 * @return 所代表远程资源的响应结果
	 */
	public static String sendPost(String url, String param) {
		PrintWriter out = null;
		BufferedReader in = null;
		String result = "";
		try {
			URL realUrl = new URL(url);
			// 打开和URL之间的连接
			URLConnection conn = realUrl.openConnection();
			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent",
					"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			// 发送POST请求必须设置如下两行
			conn.setDoOutput(true);
			conn.setDoInput(true);
			// 获取URLConnection对象对应的输出流
			out = new PrintWriter(conn.getOutputStream());
			// 发送请求参数
			out.print(param);
			// flush输出流的缓冲
			out.flush();
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(
					new InputStreamReader(conn.getInputStream()));
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		} catch (Exception e) {
			System.out.println("发送 POST 请求出现异常！" + e);
			e.printStackTrace();
		}
		// 使用finally块来关闭输出流、输入流
		finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		return result;
	}

	// 发起微信支付请求
	public static String httpsRequest(String requestUrl, String requestMethod,
			String outputStr) {
		try {
			URL url = new URL(requestUrl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();

			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			conn.setRequestMethod(requestMethod);
			conn.setRequestProperty("content-type",
					"application/x-www-form-urlencoded");
			// 当outputStr不为null时向输出流写数据
			if (null != outputStr) {
				OutputStream outputStream = conn.getOutputStream();
				// 注意编码格式
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}
			// 从输入流读取返回内容
			InputStream inputStream = conn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(
					inputStreamReader);
			String str = null;
			StringBuffer buffer = new StringBuffer();
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			// 释放资源
			bufferedReader.close();
			inputStreamReader.close();
			inputStream.close();
			inputStream = null;
			conn.disconnect();
			return buffer.toString();
		} catch (ConnectException ce) {
			System.out.println("连接超时：{}" + ce);
		} catch (Exception e) {
			System.out.println("https请求异常：{}" + e);
		}
		return null;
	}

	
	public static String byte2hex(byte[] b) {
		StringBuilder hs = new StringBuilder();
		String stmp;
		for (int n = 0; b != null && n < b.length; n++) {
			stmp = Integer.toHexString(b[n] & 0XFF);
			if (stmp.length() == 1)
				hs.append('0');
			hs.append(stmp);
		}
		return hs.toString().toUpperCase();
	}
	
	//生成很多个*号  
	public static String createAsterisk(String name) { 
		if(name.length() <= 1){
			return "*";
		}else{
			int length = name.length() - 1;
		    StringBuffer stringBuffer = new StringBuffer();  
		    for (int i = 0; i < length; i++) {  
		        stringBuffer.append("*");  
		    }  
		    String sb = stringBuffer.toString();  
		    return name.replaceAll("([\\u4e00-\\u9fa5]{1})(.*)", "$1" + sb);
		}
		
	} 
	
	
	public static String doRefund(String url,String data) throws Exception {  
        /** 
         * 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的 
         */  
          
        KeyStore keyStore  = KeyStore.getInstance("PKCS12");  
        FileInputStream instream = new FileInputStream(new File(WechatConfig.P12_PATH));//P12文件目录  
        try {  
            /** 
             * 此处要改 
             * */  
            keyStore.load(instream, WechatConfig.MCHID.toCharArray());//这里写密码..默认是你的MCHID  
        } finally {  
            instream.close();  
        }  
  
        // Trust own CA and all self-signed certs  
        /** 
         * 此处要改 
         * */  
        SSLContext sslcontext = SSLContexts.custom()  
                .loadKeyMaterial(keyStore, WechatConfig.MCHID.toCharArray())//这里也是写密码的    
                .build();  
        // Allow TLSv1 protocol only  
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(  
                sslcontext,  
                new String[] { "TLSv1" },  
                null,  
                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);  
        CloseableHttpClient httpclient = HttpClients.custom()  
                .setSSLSocketFactory(sslsf)  
                .build();  
        try {  
            HttpPost httpost = new HttpPost(url); // 设置响应头信息  
            httpost.addHeader("Connection", "keep-alive");  
            httpost.addHeader("Accept", "*/*");  
            httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");  
            httpost.addHeader("Host", "api.mch.weixin.qq.com");  
            httpost.addHeader("X-Requested-With", "XMLHttpRequest");  
            httpost.addHeader("Cache-Control", "max-age=0");  
            httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");  
            httpost.setEntity(new StringEntity(data, "UTF-8"));  
            CloseableHttpResponse response = httpclient.execute(httpost);  
            try {  
                HttpEntity entity = response.getEntity();  
  
                String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");  
                EntityUtils.consume(entity);  
               return jsonStr;  
            } finally {  
                response.close();  
            }  
        } finally {  
            httpclient.close();  
        }  
    }  
	
	
	/**
	 * 获取2个值之间的随机数
	 * @param smin
	 * @param smax
	 * @return
	 */
	public static long randomNum(int smin, int smax) {
		int range = smax - smin;
		double rand = Math.random();
		return (smin + Math.round(rand * range));
	}
	
	/**
	 * 获取2个值之间的随机数 浮点型
	 * @param min
	 * @param max
	 * @return
	 */
	public static String getRandomFloat(int min, int max){
        
        Double d = min + ((max - min) * new Random().nextDouble());  
        DecimalFormat df = new DecimalFormat("#.00");
        return df.format(d);

    }
	
	/**
	 * 获取2个值之间的随机数 整型
	 * @param min
	 * @param max
	 * @return
	 */
	public static String getRandomInt(int min, int max){
		
        Random random = new Random();
        int s = random.nextInt(max) % (max - min + 1) + min;
        return String.valueOf(s);
        
    }
	
	/**
	 * 根据银行卡号获取银行编码
	 * @param cardNo 银行卡卡号
	 * @return
	 */
	public static ResultEntity getBankCode(String cardNo){
		ResultEntity re = null;
		String bankCode = "";
		String prm = "_input_charset=utf-8&cardNo=" + cardNo + "&cardBinCheck=true";
		String jsonStr = CommonUtilsEx.sendPost("https://ccdcapi.alipay.com/validateAndCacheCardInfo.json", prm);
		Map<String, Object> res = JSONUtilsEx.deserialize(jsonStr, Map.class);
		
		if(((Boolean) res.get("validated")).booleanValue()){
			bankCode = String.valueOf(res.get("bank"));
			re = new ResultEntity("0", null, bankCode);
		}else{
			re = new ResultEntity("-1", "卡号输入有误！");
		}
		
		return re;
	}
	
	/**
     * 从HTML源码中提取标签属性，最后以一个 String 类型的 List 返回
     * 需要注意的是，（提取图片路径时）此方法只会提取以下格式的图片：.jpg|.bmp|.eps|.gif|.mif|.miff|.png|.tif|.tiff|.svg|.wmf|.jpe|.jpeg|.dib|.ico|.tga|.cut|.pic
     * @param htmlCode HTML源码
     * @param labelName 标签名称
     * @return 标签属性值的List集合
     * @author Carl He
     */
    public static List<String> getImageSrc(String htmlCode, String labelName) {
    	List<String> imgPathList = new ArrayList<String>();
        org.jsoup.nodes.Document doc = Jsoup.parse(htmlCode);  
        Elements rows = doc.select(labelName);  
        if (rows.size() > 0) { 
        	
            System.out.println("--------------------------- 查询结果 ---------------------------");  
            for (org.jsoup.nodes.Element row : rows) {
            	imgPathList.add(row.attr("src"));
			}  
            System.out.println("-----------------------------------------------------------------");  
        }
        
		return imgPathList;  

    }
    
}
